/** ***********************************************************************************
* @file         unit_demo.c
* @brief        NET 网络测试接口
* @details      主要用于封装模块测试接口函数
* @author       杨小珛
* @date         2021/02/19
* @copyright    北京高知科技有限公司    
* @version      V1.0
* @attention    无
**************************************************************************************/

#include "unit_demo.h"
#include "com_lib.h"

/*******************************定义网络接口*****************************************/

socket_handle_s socket_handle_1;  /*定义socket handle 可以同时打开6路通道*/
socket_handle_s socket_handle_2;
socket_handle_s socket_handle_3;
socket_handle_s socket_handle_4;
socket_handle_s socket_handle_5;
socket_handle_s socket_handle_6;

socket_state_t socket_state_1;   /*定义socket 网络状态*/
socket_state_t socket_state_2;
socket_state_t socket_state_3;
socket_state_t socket_state_4;
socket_state_t socket_state_5;
socket_state_t socket_state_6;

GaozSemaphoreHandle_t   socket_semaphore = 0;/*网络状态信号量*/

char *socket_taskname[] = { "SOCKET_HANDLE1","SOCKET_HANDLE2","SOCKET_HANDLE3","SOCKET_HANDLE4","SOCKET_HANDLE5","SOCKET_HANDLE6"};

static socket_handle_s * unit_socket_handle_sel( uint8_t sel );
static socket_state_t * unit_socket_state_sel( uint8_t sel );

static void unit_create_network_state_cb( void * pv);

static void unit_socket_semaphore_create(void);
//static void unit_socket_semaphore_free(void);

static void unit_socket_semaphore_put(void);
static uint8_t unit_socket_semaphore_get( uint32_t wait_time );
static uint32_t unit_socket_send_data_suc( socket_state_t * state ,uint32_t time );

/** ****************************************************************************
* @remarks       static socket_handle_s * unit_socket_handle_sel( uint8_t sel )
* @brief         socket handle 地址选择
* @param[in]     sel 选择地址的参数
* @param[out]    无
* @return        *handle 返回socket_handle 寄存器的地址
* @attention     无
*******************************************************************************/
static socket_handle_s * unit_socket_handle_sel( uint8_t sel )
{
    socket_handle_s *handle = NULL;
    switch( sel )
    {
        case 1:
            handle = &socket_handle_1;
        break;
        case 2:
            handle = &socket_handle_2;
        break;
        case 3:
            handle = &socket_handle_3; 
        break;
        case 4:
            handle = &socket_handle_4;
        break;
        case 5:
            handle = &socket_handle_5;
        break;
        case 6:
            handle = &socket_handle_6;
        break;
    }
    return handle;
}

/** ****************************************************************************
* @remarks       static socket_handle_s * unit_socket_state_sel( uint8_t sel )
* @brief         socket 创建网络的状态
* @param[in]     sel 选择地址的参数
* @param[out]    无
* @return        *state 返回socket_state_t 寄存器的地址
* @attention     无
*******************************************************************************/
static socket_state_t * unit_socket_state_sel( uint8_t sel )
{
    socket_state_t *state = NULL;
    switch( sel )
    {
        case 1:
            state = &socket_state_1;
        break;
        case 2:
            state = &socket_state_2;
        break;
        case 3:
            state = &socket_state_3; 
        break;
        case 4:
            state = &socket_state_4;
        break;
        case 5:
            state = &socket_state_5;
        break;
        case 6:
            state = &socket_state_6;
        break;
    }
    return state;
}

/** ****************************************************************************
* @remarks       static void unit_socket_semaphore_create(void)
* @brief         网络状态信号创建
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void unit_socket_semaphore_create(void)
{
    socket_semaphore = gaoz_sem_new(0);
    if( socket_semaphore == 0 )
    {
        while(1);
    }
}
#if 0
/** ****************************************************************************
* @remarks       static void unit_socket_semaphore_free(void)
* @brief         释放信号量
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void unit_socket_semaphore_free(void)
{
    gaoz_sem_free( socket_semaphore );
}
#endif
/** ****************************************************************************
* @remarks       static uint8_t unit_socket_semaphore_get( uint32_t wait_time )
* @brief         获取网络回调状态的信号量
* @param[in]     wait_time 等待信号的时间 单位S
* @param[out]    无
* @return        1 等待信号成功  ， 0 等待信号失败，超时等待
* @attention     无
*******************************************************************************/
static uint8_t unit_socket_semaphore_get( uint32_t wait_time )
{
    if(socket_semaphore == 0)
    {
        unit_socket_semaphore_create();
    }
    if( gaoz_sem_try_wait( socket_semaphore, wait_time ) == true ) //等待回应信号量
    {
        return 1;
    }
    else
    {   
        return 0;
    }
}

/** ****************************************************************************
* @remarks       void unit_socket_semaphore_put(void)
* @brief         发送消息队列
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void unit_socket_semaphore_put(void)
{
    if( socket_semaphore != 0 )
    {
        gaoz_sem_signal( socket_semaphore );
    }
}

/** ****************************************************************************
* @remarks       static uint32_t unit_socket_send_data_suc( socket_state_t * state ,uint32_t time )
* @brief         等待发送数据成功状态
* @param[in]     *state 网络状态 数据地址
* @param[in]     time 等待的时间
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static uint32_t unit_socket_send_data_suc( socket_state_t *state ,uint32_t time )
{
	uint32_t ret = pdFAIL;
    if( unit_socket_semaphore_get( time ) == 1 )
    {
    	/******************判断网络数据是否发生完成****************************/
    	if( state->network_run_state.send_st == SEND_OK )
    	{
            state->network_run_state.send_st = 0;
    		ret = pdPASS;
    	}
    }
	return ret;
}

/** ****************************************************************************
* @remarks       static uint32_t unit_create_network_state_cb( uint8_t n , uint8_t *arg )
* @brief         NET网络状态回调函数
* @param[in]     *pv 不定类型的函数入参 
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void unit_create_network_state_cb( void *pv)
{
    uint8_t  print_buf[100] = { 0 };
    uint16_t print_len = 0;
	socket_net_state_s *net_state = NULL;
    socket_state_t *state = NULL;
	if( pv == NULL )				/*空指针返回*/
	{
		return;
	}
	net_state = ( socket_net_state_s * )pv;
    state = unit_socket_state_sel( net_state->index_id + 1 );
    print_len = sprintf((char *)print_buf,"Network status:%d,%d\r\n",net_state->index_id ,net_state->net_state);
    gaoz_usb_driver_send_data( print_buf, print_len );
	switch( net_state->net_state )
	{
	    case SOCKET_STATE_INIT:
            /*无*/
            break;
		case SOCKET_SEND_OK:		/*数据发送成功*/
			state->network_run_state.send_st = SEND_OK;
			break;
		case SOCKET_SEND_ERROR:		/*数据发送失败*/
			state->network_run_state.send_st = SEND_ERR;
			break;
		case SOCKET_RECV_OK:		/*数据接收成功*/
			state->network_run_state.recv_st = RECV_OK;
			break;
		case SOCKET_RECV_ERROR:		/*数据接收失败*/
			state->network_run_state.recv_st = RECV_ERR;
			break;
		case SOCKET_LINK_ERROR:		/*网络连接失败*/
			state->network_run_state.link_st = LINK_ERR;
			break;
		case SOCKET_CSQ_ERROR:		/*网络信息状态异常*/
			state->network_run_state.csq_st = CSQ_ERR;
			break;
		case SOCKET_REG_ERROR:		/*网络附着网络失败*/
			state->network_run_state.reg_st = REG_ERR;
			break;
		case GSM_NET_SLEEP:			/*底层网络睡眠*/
			state->network_run_state.net_st = NET_SLEEP;
			break;
		case GSM_NET_STOP:			/*底层网络停止*/
			state->network_run_state.net_st = NET_STOP;
			break;
		case GSM_NET_RST:			/*底层网络需要复位*/
			state->network_run_state.net_st = NET_RST;
			break;
		case GSM_NET_RUN:			/* 底层网络运行中*/
			state->network_run_state.net_st = NET_RUN;
			break;
	}
    unit_socket_semaphore_put(); /*发送信号量*/
}

/** ****************************************************************************
* @remarks       static uint32_t unit_net_open( uint8_t n , uint8_t *arg )
* @brief         NET 网络打开操作
* @param[in]     n 参数数据 n最大参数为3个 
* @param[in]     uint8_t *arg 可变参数 配置参数必须为3个 x x "x" x 
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_net_open( uint8_t n , uint8_t *arg )
{
    uint8_t step = 0;
    uint16_t arg_len = 0;
    uint16_t port = 0;
    uint32_t ret = pdFAIL;
    uint8_t ip[MAX_IP_LEN] = { 0 };
    uint8_t  print_buf[200] = { 0 };
    uint16_t print_len = 0;
    socket_handle_s *handle = NULL;
    socket_state_t *state = NULL;
    unit_arg_int8_type *arg_int8 = NULL;
    unit_arg_int16_type *arg_int16 = NULL;
    unit_arg_str_type *unit_arg_str = NULL;
    if( n != 3 ) /**/
    {
        return  pdFAIL;
    }
    /*1、解析将要被打开的handle ID*/
    if( step == 0 )
    {
        arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
        arg_len += sizeof( unit_arg_int8_type );
        if(( arg_int8->num == 1 ) 
            && ( arg_int8->len == 0x01 ) 
            && (( arg_int8->arg > 0 ) && ( arg_int8->arg <= MAX_SOCKET_CONN_NUM )))
        {
            handle = unit_socket_handle_sel( arg_int8->arg );
            state = unit_socket_state_sel( arg_int8->arg );
            if( handle->connStaus == 0 )  /*判断网络handle 是否已经被使用*/
            {
                unit_socket_semaphore_create();
                gaoz_socket_default( (socket_handle_s *)handle );    /*初始化网络参数*/
                print_len = sprintf((char *)print_buf,"Network index:%d\r\n",( arg_int8->arg ));
                gaoz_usb_driver_send_data( print_buf, print_len );
                step ++;
            }
            else
            {
                return pdFAIL;
            }
        }
    }
    /*2、解析服务器的IP地址*/
    if( step == 1 )
    {
        unit_arg_str = (unit_arg_str_type *)&arg[arg_len];
        if(( unit_arg_str->num == 2 ) 
            && (( unit_arg_str->len > 0 ) && ( unit_arg_str->len < UNIT_ARG_STR_MAX_LEN )))
        {
            memset( ( uint8_t *)ip , 0x00 , MAX_IP_LEN );
            memcpy((char*)ip, (char*)unit_arg_str->arg ,unit_arg_str->len );
            print_len = sprintf((char *)print_buf,"Network ip:%s\r\n",ip);
            gaoz_usb_driver_send_data( print_buf, print_len );
            step ++;
        }
        arg_len += unit_arg_str->len + 3;
    }
    /*3、解析服务器的端口号*/
    if( step == 2 )
    {
        arg_int16 =(unit_arg_int16_type *)&arg[arg_len];
        arg_len += sizeof( unit_arg_int16_type );
        if(( arg_int16->num == 3 ) && ( arg_int16->len == 2 ) && ( arg_int16->arg != 0 ))
        {
            port = arg_int16->arg;
            print_len = sprintf((char *)print_buf,"Network port:%d\r\n",port);
            gaoz_usb_driver_send_data( print_buf, print_len );
            step ++;
        }
    }
    /*4、连接服务器*/
    if( step == 3 )
    {
        gaoz_socket_bind((socket_handle_s*)handle, (char *)ip, port, e_socket_protocol_tcp, unit_create_network_state_cb );
        ret = gaoz_socket_connect( (socket_handle_s*)handle );
        if( ret == pdPASS )
        {
            state->create_socket_state = SOCKET_LINK_CREATE_OK;
            print_len = sprintf((char *)print_buf,"Network open successful:%d,%s,%d\r\n",handle->connIndex,handle->ip,handle->port);
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
    }
    return ret;
}

/** ****************************************************************************
* @remarks       static uint32_t unit_net_write( uint8_t n , uint8_t *arg )
* @brief         NET 网络发送数据
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_net_write( uint8_t n , uint8_t *arg )
{
    uint8_t step = 0;
    uint8_t *write_buf =NULL;
    uint16_t arg_len = 0;
    uint16_t write_len = 0;
    socket_handle_s *handle = NULL;
    socket_state_t *state = NULL;
    unit_arg_int8_type *arg_int8 = NULL;
    unit_arg_str_type *unit_arg_str = NULL;
    uint8_t  *print_buf = NULL;
    uint16_t print_len = 0;
    uint32_t ret = pdFAIL;
    if( n != 2 ) /**/
    {
        return  pdFAIL;
    }
    print_buf = ( uint8_t *)gaoz_malloc_mem( arg_len * 2 + 100 ); /*动态申请空间，空间位置处于FreeRtos总栈空间中*/
    if( print_buf == NULL )
    {
        return  pdFAIL;
    }
    /*1、解析将要被打开的handle ID*/
    if( step == 0 )
    {
        arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
        arg_len += sizeof( unit_arg_int8_type );
        if(( arg_int8->num == 1 ) 
            && ( arg_int8->len == 0x01 ) 
            && (( arg_int8->arg > 0 ) && ( arg_int8->arg <= MAX_SOCKET_CONN_NUM )))
        {
            handle = unit_socket_handle_sel( arg_int8->arg );
            state = unit_socket_state_sel( arg_int8->arg );
            if( handle->connStaus == 1 )  /*判断网络handle 是否已经被使用*/
            {
                print_len = sprintf((char *)print_buf,"Write index:%d\r\n",( arg_int8->arg ));
                gaoz_usb_driver_send_data( print_buf, print_len );
                step ++;
            }
            else
            {
               ret = pdFAIL;
            }
        }
    }
    /*2、解析向服务器发送的数据和长度，向服务器发送数据*/
    if( step == 1 )
    {
        unit_arg_str = (unit_arg_str_type *)&arg[arg_len];
        if(( unit_arg_str->num == 2 ) 
            && (( unit_arg_str->len > 0 ) && ( unit_arg_str->len < UNIT_ARG_STR_MAX_LEN )))
        {
            write_len = unit_arg_str->len;
            write_buf = unit_arg_str->arg;
            step ++;
        }
        arg_len += unit_arg_str->len + 3;
    }
    /*3、向服务器发送数据*/
    if( step == 2 )
    {
        ret = gaoz_socket_write( (socket_handle_s *)handle , write_buf , write_len );
        if( ret == pdPASS )
        {   
            if( unit_socket_send_data_suc( state ,1000 ) == pdPASS ) /*检测底层回调函数的结果，是否已经发生成功*/
            {   
                print_len = sprintf((char *)print_buf,"Write data:%d,%s\r\n",write_len ,write_buf);
                gaoz_usb_driver_send_data( print_buf, print_len );
            }
            else
            {
                ret = pdFAIL;
            }
        }
    }
    if( print_buf != NULL )
    {
        gaoz_free_mem( (void *)print_buf );
    }
    return ret;
}

/** ****************************************************************************
* @remarks       static void  unit_net_read_handle_task( void * pvParameters)
* @brief         单元测试网络接收数据任务
* @param[in]     * pvParameters 任务参数
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void  unit_net_read_handle_task( void * pvParameters)
{ 
    uint8_t *read_buf = NULL;
    uint16_t read_len = 0;
    socket_handle_s *handle = NULL;
    uint8_t *index = NULL;
    uint8_t  print_buf[100] = { 0 };
    uint16_t print_len = 0;
    index = ( uint8_t * )pvParameters;
    handle = unit_socket_handle_sel( *index );
    read_buf = (uint8_t *)gaoz_fibo_malloc( NET_RECV_DATA_LEN + 8 );
    for( ;; )
    {
        read_len = socket_recv( (socket_handle_s  *)handle, read_buf ,1000 );
        if( read_len >0 ) 
        {
            print_len = sprintf((char *)print_buf,"Read data:%d,",read_len);
            gaoz_usb_driver_send_data( print_buf, print_len );
            read_buf[read_len] = '\r';
            read_len++;
            read_buf[read_len] = '\n';
            read_len++;
            gaoz_usb_driver_send_data( read_buf, read_len );
        }
        if( handle->connStaus == 0 ) /*检测当前网络节点是否被关闭，关闭后删除任务*/
        {
            gaoz_fibo_free( (void *)read_buf );
            print_len = sprintf((char *)print_buf,"Read task exit:%s\r\n",socket_taskname[*index - 1]);
            gaoz_usb_driver_send_data( print_buf, print_len );
            gaoz_thread_delete();
        }
    }
}
/** ****************************************************************************
* @remarks       static uint32_t unit_net_read( uint8_t n , uint8_t *arg )
* @brief         NET 读取数据
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_net_read( uint8_t n , uint8_t *arg )
{
    uint16_t arg_len = 0;
    socket_handle_s *handle = NULL;
    unit_arg_int8_type *arg_int8 = NULL;
    uint8_t  print_buf[200] = { 0 };
    uint16_t print_len = 0;
    uint32_t ret = pdFAIL;
    if( n != 1 )
    {
        return  pdFAIL;
    }
    arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
    arg_len += sizeof( unit_arg_int8_type );
    if(( arg_int8->num == 1 ) 
        && ( arg_int8->len == 0x01 ) 
        && (( arg_int8->arg > 0 ) && ( arg_int8->arg <= MAX_SOCKET_CONN_NUM )))
    {
        handle = unit_socket_handle_sel( arg_int8->arg );
        if( handle->connStaus == 1 )  /*判断网络handle 是否已经被使用*/
        {   
            print_len = sprintf((char *)print_buf,"Read index:%d\r\n",( arg_int8->arg ));
            gaoz_usb_driver_send_data( print_buf, print_len );
            if( gaoz_thread_create(unit_net_read_handle_task, socket_taskname[ arg_int8->arg - 1 ], 1024*2, (void *)&arg_int8->arg, OSI_PRIORITY_NORMAL) == 0 )
            {
                print_len = sprintf((char *)print_buf,"Read task creat successful:%s\r\n",socket_taskname[arg_int8->arg - 1]);
                gaoz_usb_driver_send_data( print_buf, print_len );
            }
        }
        else
        {
            return ret;
        }
    }
    return pdPASS;
}

/** ****************************************************************************
* @remarks       static uint32_t unit_net_close( uint8_t n , uint8_t *arg )
* @brief         NET 关闭网络
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_net_close( uint8_t n , uint8_t *arg )
{
    uint32_t ret = pdFAIL;
    socket_handle_s *handle = NULL;
    unit_arg_int8_type *arg_int8 = NULL;
    uint8_t  print_buf[200] = { 0 };
    uint16_t print_len = 0;
    if( n != 1 ) /*关闭网络参数为1*/
    {
        return  pdFAIL;
    }
    
    /*解析将要被打开的handle ID*/
    arg_int8 =(unit_arg_int8_type *)arg;
    if((arg_int8->num == 1 ) 
        && ( arg_int8->len == 0x01 ) 
        && (( arg_int8->arg > 0 ) && ( arg_int8->arg <= MAX_SOCKET_CONN_NUM )))
    {
        print_len = sprintf( (char *)print_buf,"Network index:%d\r\n",( arg_int8->arg ) );
        gaoz_usb_driver_send_data( print_buf, print_len );
        handle = unit_socket_handle_sel( arg_int8->arg );         /*获取到网络的handle */
        if( handle->connStaus == 1 )                                /*判断网络handle 是否已经被使用*/
        {
            ret = gaoz_socket_close((socket_handle_s*)handle);    /*管理网络链接*/
            if( ret == pdPASS )
            {
                print_len = sprintf((char *)print_buf,"Network shutdown successful:%d,%s,%d\r\n",handle->connIndex,handle->ip,handle->port);
                gaoz_usb_driver_send_data( print_buf, print_len );
            }
        }
        else
        {
            return pdFAIL;
        }
    }
    return ret;
}

const unit_test_interface_typedef unit_net_mod =
{
    UNIT_NET,            	// 模块类型
    "NET",              	// 模块名称
    unit_net_open,
    unit_net_write, 	
    unit_net_read,
    NULL,
    unit_net_close,
};

/*******************************定义MCU接口*****************************************/

/** ****************************************************************************
* @remarks       static uint32_t unit_mcu_open( uint8_t n , uint8_t *arg )
* @brief         MCU打开操作
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_mcu_open( uint8_t n , uint8_t *arg )
{
    return pdPASS;
}

/** ****************************************************************************
* @remarks       static uint32_t unit_mcu_write( uint8_t n , uint8_t *arg )
* @brief         MCU写数据
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_mcu_write( uint8_t n , uint8_t *arg )
{
    return pdPASS;
}
/** ****************************************************************************
* @remarks       static uint32_t unit_mcu_close( uint8_t n , uint8_t *arg )
* @brief         MCU读数据
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_mcu_close( uint8_t n , uint8_t *arg )
{
    return pdPASS;
}

const unit_test_interface_typedef unit_mcu_mod =
{
    UNIT_MCU,            	// 模块类型
    "MCU",              	// 模块名称
    unit_mcu_open,	
    unit_mcu_write,       	
    NULL,         	
    NULL, 
    unit_mcu_close,
};

/*******************************定义FLASH接口*****************************************/
#define UNIT_FLASH_DATA_LEN     128
const sfb_setting_t sfb_set_test=
{ 
    SF_SFB_HANDLE_ADDR,
    SF_SAVE_DATA_ADDR,
    SPI_FLASH_MIN_SECTOR,
    SF_SAVE_DATA_FlAG_SECTORS,
    UNIT_FLASH_DATA_LEN,
    SPI_FLASH_MIN_SECTOR / UNIT_FLASH_DATA_LEN,
};

sfb_buf_rt_t sfb_handle_test;
uint32_t sfb_handle_id;
/** ****************************************************************************
* @remarks       static uint32_t unit_flash_open( uint8_t n , uint8_t *arg )
* @brief         FLASH 打开，进入工作模式
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_flash_open( uint8_t n , uint8_t *arg )
{
    uint16_t arg_len = 0;
    uint32_t ret = pdFAIL ;
    uint8_t  print_buf[100] = { 0 };
    uint16_t print_len = 0;
    unit_arg_int8_type *arg_int8 = NULL;
    
    if( n != 1 )
    {
        return  pdFAIL;
    }
    arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
    arg_len += sizeof( unit_arg_int8_type );
    if(( arg_int8->num == 1 )&& ( arg_int8->len == 0x01 ))
    {
        if( arg_int8->arg == 1 )
        {   
            ret = gaoz_save_data_open( &sfb_handle_test ,&sfb_set_test ,&sfb_handle_id );
            if( ret == pdPASS )
            {
                print_len = sprintf( (char *)print_buf,"Flash open successful:%d\r\n",arg_int8->arg );
                gaoz_usb_driver_send_data( print_buf, print_len );
            }
        }
    }
    return pdPASS;
}

/** ****************************************************************************
* @remarks       static uint32_t unit_flash_write( uint8_t n , uint8_t *arg )
* @brief         FLASH 写数据
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_flash_write( uint8_t n , uint8_t *arg )
{
    uint8_t step = 0;
    uint8_t *write_buf =NULL;
    uint16_t arg_len = 0;
    uint16_t write_len = 0;
    unit_arg_int8_type *arg_int8 = NULL;
    unit_arg_str_type *unit_arg_str = NULL;
    uint8_t  *print_buf = NULL;
    uint16_t print_len = 0;
    uint32_t ret = pdFAIL;
    if( n != 2 ) /**/
    {
        return  pdFAIL;
    }
    print_buf = ( uint8_t *)gaoz_malloc_mem( arg_len * 2 + 100 ); /*动态申请空间，空间位置处于FreeRtos总栈空间中*/
    if( print_buf == NULL )
    {
        return  pdFAIL;
    }
    /*1、解析将要被打开的handle ID*/
    if( step == 0 )
    {
        arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
        arg_len += sizeof( unit_arg_int8_type );
        if(( arg_int8->num == 1 ) 
            && ( arg_int8->len == 0x01 ) 
            && (( arg_int8->arg > 0 ) && ( arg_int8->arg <= SAVE_RAM_OPEN_MAX_NUM )))
        {
            print_len = sprintf((char *)print_buf,"Write index:%d\r\n",( arg_int8->arg ));
            gaoz_usb_driver_send_data( print_buf, print_len );
            step ++;
        }
    }
    /*2、解析发送的数据和长度，向发送数据*/
    if( step == 1 )
    {
        unit_arg_str = (unit_arg_str_type *)&arg[arg_len];
        if(( unit_arg_str->num == 2 ) 
            && (( unit_arg_str->len > 0 ) && ( unit_arg_str->len < UNIT_ARG_STR_MAX_LEN )))
        {
            write_len = unit_arg_str->len;
            write_buf = unit_arg_str->arg;
            step ++;
        }
        arg_len += unit_arg_str->len + 3;
    }
    /*3、写数据*/
    if( step == 2 )
    {
        ret = gaoz_save_data_write( sfb_handle_id , write_buf , write_len );
        if( ret == pdPASS )
        {   
            print_len = sprintf((char *)print_buf,"Write data:%d,%s\r\n",write_len ,write_buf);
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
    }
    
    if( print_buf != NULL )
    {
        gaoz_free_mem( (void *)print_buf );
    }
    return ret;
}

/** ****************************************************************************
* @remarks       static uint32_t unit_flash_read( uint8_t n , uint8_t *arg )
* @brief         FLASH 读数据
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_flash_read( uint8_t n , uint8_t *arg )
{
    uint16_t arg_len = 0;
    unit_arg_int8_type *arg_int8 = NULL;
    uint8_t  print_buf[UNIT_FLASH_DATA_LEN +50] = { 0 };
    uint16_t print_len = 0;
    uint32_t ret = pdFAIL;
    uint8_t read_buf[UNIT_FLASH_DATA_LEN] = { 0 };
    uint16_t read_len = 0;
    if( n != 1 )
    {
        return  pdFAIL;
    }
    arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
    arg_len += sizeof( unit_arg_int8_type );
    if(( arg_int8->num == 1 ) 
        && ( arg_int8->len == 0x01 ) 
        && (( arg_int8->arg > 0 ) && ( arg_int8->arg <= SAVE_RAM_OPEN_MAX_NUM )))
    {
        print_len = sprintf((char *)print_buf,"Read index:%d\r\n",( arg_int8->arg ));
        gaoz_usb_driver_send_data( print_buf, print_len );
        ret = gaoz_save_data_read( sfb_handle_id , read_buf , &read_len );
        if( ret != 0 )
        {
            print_len = sprintf((char *)print_buf,"Read data:%d,%s\r\n",read_len ,read_buf );
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
    }
    return ret;
}

/** ****************************************************************************
* @remarks       static uint32_t unit_flash_close( uint8_t n , uint8_t *arg )
* @brief         FLASH 关闭，进入低功耗模式
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_flash_close( uint8_t n , uint8_t *arg )
{
    uint16_t arg_len = 0;
    uint32_t ret = pdFAIL ;
    uint8_t  print_buf[100] = { 0 };
    uint16_t print_len = 0;
    unit_arg_int8_type *arg_int8 = NULL;
    
    if( n != 1 )
    {
        return  pdFAIL;
    }
    arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
    arg_len += sizeof( unit_arg_int8_type );
    if(( arg_int8->num == 1 )&& ( arg_int8->len == 0x01 ))
    {
        if( arg_int8->arg == 1 )
        {   
            ret = gaoz_save_data_close( sfb_handle_id );
            if( ret == pdPASS )
            {
                print_len = sprintf( (char *)print_buf,"Flash close successful:%d\r\n",arg_int8->arg );
                gaoz_usb_driver_send_data( print_buf, print_len );
            }
        }
    }
    
    return pdPASS;
}

const unit_test_interface_typedef unit_flash_mod =
{
    UNIT_FLASH,            	// 模块类型
    "FLASH",              	// 模块名称
    unit_flash_open,	
    unit_flash_write,       	
    unit_flash_read,         	
    NULL,
    unit_flash_close,
};

/*******************************定义RTC接口*****************************************/

/** ****************************************************************************
* @remarks       static uint32_t unit_rtc_write( uint8_t n , uint8_t *arg )
* @brief         FLASH 写数据
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_rtc_write( uint8_t n , uint8_t *arg )
{
    uint8_t  print_buf[100] = { 0 };
    uint16_t print_len = 0;
    uint32_t ret = pdFAIL;
    uint16_t arg_len = 0;
    uint32_t timestamp = 0;
    rtc_struct rtc_s ;
    en_sys_rtc_type_t rtc_t;
    unit_arg_int32_type *arg_int32 = NULL;
    unit_arg_int16_type *arg_int16 = NULL;
    unit_arg_int8_type *arg_int8 = NULL;
    if(( n > 7 ) || ( n == 0 ))
    {
        return  pdFAIL;
    }
    /*获取设置的类型*/
    arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
    if(( arg_int8->num = 0x01 ) && ( arg_int8->len == 0x01 ))
    {
        if( arg_int8->arg > RTC_TIM_CAL_BCD )
        {
            return  pdFAIL;
        }
        rtc_t = (en_sys_rtc_type_t)arg_int8->arg;
    }
    else
    {
        return  pdFAIL;
    }
    arg_len += sizeof(unit_arg_int8_type);
    /*时间戳方式设置时间*/
    if( rtc_t == RTC_TIM_TIMESTAMP )
    {
        arg_int32 =(unit_arg_int32_type *)&arg[arg_len];
        if(( arg_int32->num = 0x02 ) && ( arg_int16->len == 0x04 ))
        {
            timestamp = arg_int32->arg;
        }
        ret = gaoz_rtc_sys_set( RTC_TIM_TIMESTAMP, (uint32_t *)&timestamp );
        if( ret == pdPASS ) /*设置时间正确*/
        {
            gaoz_rtc_sys_get( RTC_TIM_TIMESTAMP, (uint32_t *)&timestamp);
            print_len = sprintf((char *)print_buf,"RT_TIM_TIMESTAMP:%d\r\n",(UINT32)timestamp);
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
    }
    else /*时钟方式设置时间*/
    {
        /*年*/
        arg_int16 =(unit_arg_int16_type *)&arg[arg_len];
        if(( arg_int16->num = 0x02 ) && ( arg_int16->len == 0x02 ))
        {
            rtc_s.year = arg_int16->arg;
        }
        arg_len += sizeof(unit_arg_int16_type);
        /*月*/
        arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
        if(( arg_int8->num = 0x03 ) && ( arg_int8->len == 0x01 ))
        {
            rtc_s.month = arg_int8->arg;
        }
        arg_len += sizeof(unit_arg_int8_type);
        /*日*/
        arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
        if(( arg_int8->num = 0x04 ) && ( arg_int8->len == 0x01 ))
        {
            rtc_s.day = arg_int8->arg;
        }
        arg_len += sizeof(unit_arg_int8_type);
        /*时*/
        arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
        if(( arg_int8->num = 0x05 ) && ( arg_int8->len == 0x01 ))
        {
            rtc_s.hour = arg_int8->arg;
        }
        arg_len += sizeof(unit_arg_int8_type);
        /*分*/
        arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
        if(( arg_int8->num = 0x06 ) && ( arg_int8->len == 0x01 ))
        {
            rtc_s.minute = arg_int8->arg;
        }
        arg_len += sizeof(unit_arg_int8_type);
        /*秒*/
        arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
        if(( arg_int8->num = 0x07 ) && ( arg_int8->len == 0x01 ))
        {
            rtc_s.second = arg_int8->arg;
        }
        ret = gaoz_rtc_sys_set( rtc_t, (rtc_struct *)&rtc_s );

        if( ret == pdPASS ) /*设置时间正确*/
        {
           if( rtc_t == RTC_TIM_CAL_INT ) 
           {
               gaoz_rtc_sys_get( RTC_TIM_CAL_INT, (rtc_struct *)&rtc_s);
               print_len = sprintf((char *)print_buf,"RTC_TIM_CAL_INT:%d %d %d %d %d %d\r\n",
                                        rtc_s.year,rtc_s.month,rtc_s.day,rtc_s.hour,rtc_s.minute,rtc_s.second);
               gaoz_usb_driver_send_data( print_buf, print_len );
           }
           else if( rtc_t == RTC_TIM_CAL_BCD )
           {
               gaoz_rtc_sys_get( RTC_TIM_CAL_BCD, (rtc_struct *)&rtc_s);
               print_len = sprintf((char *)print_buf,"RTC_TIM_CAL_INT:%x %x %x %x %x %x\r\n",
                                        rtc_s.year,rtc_s.month,rtc_s.day,rtc_s.hour,rtc_s.minute,rtc_s.second);
               gaoz_usb_driver_send_data( print_buf, print_len );
           }
        }
    }
    return ret;
}

/** ****************************************************************************
* @remarks       static uint32_t unit_rtc_read( uint8_t n , uint8_t *arg )
* @brief         FLASH 读数据
* @param[in]     n 参数数据 参数的个数为5
* @param[in]     uint8_t *arg 可变参数  参数为:0 1 2 3 4
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_rtc_read( uint8_t n , uint8_t *arg )
{  
    uint8_t i = 0;
    uint8_t buf[50] = { 0 };
    uint8_t  print_buf[100] = { 0 };
    uint16_t print_len = 0;
    uint16_t arg_len = 0;
    rtc_struct rtc_s;
    uint32_t timestamp = 0;
    unit_arg_int8_type *arg_int8 = NULL;
    if(( n > 5 )|| ( n == 0 )) /*参数最大为5个*/
    {
       return  pdFAIL;
    }
    for( i  = 0 ; i < n ; i ++ )
    {
        arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
        arg_len += sizeof( unit_arg_int8_type );
        if( arg_int8->arg == RTC_TIM_TIMESTAMP)
        {
            gaoz_rtc_sys_get( RTC_TIM_TIMESTAMP, (uint32_t *)&timestamp);
            print_len = sprintf((char *)print_buf,"RT_TIM_TIMESTAMP:%d\r\n",(UINT32)timestamp);
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
        else if( arg_int8->arg == RTC_TIM_CAL_INT )
        {
            gaoz_rtc_sys_get( RTC_TIM_CAL_INT, (rtc_struct *)&rtc_s);
            print_len = sprintf((char *)print_buf,"RTC_TIM_CAL_INT:%d %d %d %d %d %d\r\n",
                                rtc_s.year,rtc_s.month,rtc_s.day,rtc_s.hour,rtc_s.minute,rtc_s.second);
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
        else if( arg_int8->arg == RTC_TIM_CAL_BCD )
        {
            gaoz_rtc_sys_get( RTC_TIM_CAL_BCD, (rtc_struct *)&rtc_s);
            print_len = sprintf((char *)print_buf,"RTC_TIM_CAL_BCD:%x %x %x %x %x %x\r\n",
                                rtc_s.year,rtc_s.month,rtc_s.day,rtc_s.hour,rtc_s.minute,rtc_s.second);
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
        else if( arg_int8->arg == RTC_TIM_STRING )
        {
            memset( (uint8_t *)buf , 0x00 , sizeof( buf ));
            gaoz_rtc_sys_get( RTC_TIM_STRING, (uint8_t *)buf);
            print_len = sprintf((char *)print_buf,"RTC_TIM_CAL_BCD:%s\r\n",buf);
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
        else if( arg_int8->arg == RTC_TIM_ASCII )
        {
            memset( (uint8_t *)buf , 0x00 , sizeof( buf ));
            gaoz_rtc_sys_get( RTC_TIM_ASCII, (uint8_t *)buf);
            print_len = sprintf((char *)print_buf,"RTC_TIM_ASCII:%s\r\n",buf);
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
        else
        {
            gaoz_rtc_sys_get( (en_sys_rtc_type_t)arg_int8->arg, (rtc_struct *)&rtc_s);
            print_len = sprintf((char *)print_buf,"RTC_TIM_CAL_INT:%d %d %d %d %d %d\r\n",
                               rtc_s.year,rtc_s.month,rtc_s.day,rtc_s.hour,rtc_s.minute,rtc_s.second);
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
    }
    return pdPASS;
}

const unit_test_interface_typedef unit_rtc_mod =
{
    UNIT_RTC,            	// 模块类型
    "RTC",              	// 模块名称
    NULL,	
    unit_rtc_write,
    unit_rtc_read,         	
    NULL,
    NULL,
};

/*******************************定义GPS接口*****************************************/

/** ****************************************************************************
* @remarks       static uint32_t unit_gps_read( uint8_t n , uint8_t *arg )
* @brief         GNSS数据读写
* @param[in]     n 参数数据
* @param[in]     uint8_t *arg 可变参数
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     无
*******************************************************************************/
static uint32_t unit_gps_read( uint8_t n , uint8_t *arg )
{
    unit_arg_int8_type *arg_int8 = NULL;
    uint16_t arg_len = 0;
    uint8_t  print_buf[512] = { 0 };
    uint16_t print_len = 0;
    uint32_t ret = pdFAIL, value = 0;
    gnss_info_struct gnss_info;
    
    if( n != 1 )
    {
       return  pdFAIL;
    }
    arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
    arg_len += sizeof( unit_arg_int8_type );
    if(( arg_int8->num == 0x01 ) && ( arg_int8->len == 0x01 )) 
    {
        if( arg_int8->arg == 0x01 )         /*读取GPS 原始报文数据*/
        {
            gaoz_gnss_info_now_get( &gnss_info );
            print_len = sprintf((char *)print_buf,"Gnss read:time:%x%x%x%x%x%x,valid:%d,ggafs:%d,satnum:%d,posflag:%d,nsi:%d,ewi:%d,lat:%d,lon:%d,alt:%d,spd:%d,dir:%d\r\n",
                                                   gnss_info.gnss_position_info.time.year,
                                                   gnss_info.gnss_position_info.time.month,
                                                   gnss_info.gnss_position_info.time.day,
                                                   gnss_info.gnss_position_info.time.hour,
                                                   gnss_info.gnss_position_info.time.minute,
                                                   gnss_info.gnss_position_info.time.second,
                                                   gnss_info.gnss_position_info.is_valid,
                                                   gnss_info.gnss_position_info.gga_fs,
                                                   gnss_info.gnss_position_info.sat_num,
                                                   gnss_info.gnss_position_info.pos_flag,
                                                   gnss_info.gnss_position_info.nsi,
                                                   gnss_info.gnss_position_info.ewi,
                                                   (UINT32)gnss_info.gnss_position_info.latitude,
                                                   (UINT32)gnss_info.gnss_position_info.longitude,
                                                   (INT32)gnss_info.gnss_position_info.altitude,
                                                   gnss_info.gnss_position_info.speed,
                                                   gnss_info.gnss_position_info.direction );  
            gaoz_usb_driver_send_data( print_buf, print_len );
            ret = pdPASS;
        }
        else if( arg_int8->num == 0x02 )
        {
            gaoz_gnss_info_old_get( &gnss_info );
            print_len = sprintf((char *)print_buf,"Gnss read:time:%x%x%x%x%x%x,valid:%d,ggafs:%d,satnum:%d,posflag:%d,nsi:%d,ewi:%d,lat:%d,lon:%d,alt:%d,spd:%d,dir:%d\r\n",
                                                       gnss_info.gnss_position_info.time.year,
                                                       gnss_info.gnss_position_info.time.month,
                                                       gnss_info.gnss_position_info.time.day,
                                                       gnss_info.gnss_position_info.time.hour,
                                                       gnss_info.gnss_position_info.time.minute,
                                                       gnss_info.gnss_position_info.time.second,
                                                       gnss_info.gnss_position_info.is_valid,
                                                       gnss_info.gnss_position_info.gga_fs,
                                                       gnss_info.gnss_position_info.sat_num,
                                                       gnss_info.gnss_position_info.pos_flag,
                                                       gnss_info.gnss_position_info.nsi,
                                                       gnss_info.gnss_position_info.ewi,
                                                       (UINT32)gnss_info.gnss_position_info.latitude,
                                                       (UINT32)gnss_info.gnss_position_info.longitude,
                                                       (INT32)gnss_info.gnss_position_info.altitude,
                                                       gnss_info.gnss_position_info.speed,
                                                       gnss_info.gnss_position_info.direction );
            gaoz_usb_driver_send_data( print_buf, print_len );
            ret = pdPASS;
        }
        else if( arg_int8->num == 0x03 )
        {   
            ret = gnss_speed_get( &value ); /*获取当前GPS速度*/
            if( ret == pdPASS )
            {
                print_len = sprintf( (char *)print_buf,"Gnss speed:%d\r\n", (UINT32)value );
                gaoz_usb_driver_send_data( print_buf, print_len );
            }
        }
        else if( arg_int8->num == 0x04 )
        {
            value = gnss_ant_atate_get();
            print_len = sprintf( (char *)print_buf,"Gnss ant st:%d\r\n", (UINT32)value );
            gaoz_usb_driver_send_data( print_buf, print_len );
            ret = pdPASS;
        }
        else if( arg_int8->num == 0x05 )
        {
            value = gnss_status_get();
            print_len = sprintf( (char *)print_buf,"Gnss mod st:%d\r\n", (UINT32)value );
            gaoz_usb_driver_send_data( print_buf, print_len );
            ret = pdPASS;
        }
    }
    return ret;
}

const unit_test_interface_typedef unit_gps_mod =
{
    UNIT_GPS,            	// 模块类型
    "GPS",              	// 模块名称
    NULL,	
    NULL,       	
    unit_gps_read,         	
    NULL,
    NULL,
};

/************************************************************************************************
BLE测试用例
************************************************************************************************/

uint8_t ble_connect_st = 0;
static uint32_t unit_ble_open( uint8_t n , uint8_t *arg )
{
    uint16_t arg_len = 0;
    uint32_t ret = pdFAIL ;
    uint8_t  print_buf[100] = { 0 };
    uint16_t print_len = 0;
    unit_arg_int8_type *arg_int8 = NULL;
    
    if( n != 1 )
    {
        return  pdFAIL;
    }
    arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
    arg_len += sizeof( unit_arg_int8_type );
    if(( arg_int8->num == 1 )&& ( arg_int8->len == 0x01 ))
    {
        if( arg_int8->arg == 1 )
        {   
            ret = gaoz_ble_drive_data_open( "GAOZ_BLE_001" ,NULL );
            if( ret == pdPASS )
            {
                ble_connect_st = 1;
                print_len = sprintf( (char *)print_buf,"BLE open successful:%d\r\n",arg_int8->arg );
                gaoz_usb_driver_send_data( print_buf, print_len );
                ret = pdPASS;
            }
        }
    }
    
    return ret;
}


static uint32_t unit_ble_write( uint8_t n , uint8_t *arg )
{
    uint8_t step = 0;
    uint8_t *write_buf =NULL;
    uint16_t arg_len = 0;
    uint16_t write_len = 0;
    unit_arg_int8_type *arg_int8 = NULL;
    unit_arg_str_type *unit_arg_str = NULL;
    uint8_t  *print_buf = NULL;
    uint16_t print_len = 0;
    uint32_t ret = pdFAIL;
    if( n != 2 ) /**/
    {
        return  pdFAIL;
    }
    print_buf = ( uint8_t *)gaoz_malloc_mem( arg_len * 2 + 100 ); /*动态申请空间，空间位置处于FreeRtos总栈空间中*/
    if( print_buf == NULL )
    {
        return  pdFAIL;
    }
    /*1、解析将要被打开的handle ID*/
    if( step == 0 )
    {
        arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
        arg_len += sizeof( unit_arg_int8_type );
        if(( arg_int8->num == 1 ) 
            && ( arg_int8->len == 0x01 ) 
            && ( arg_int8->arg > 0 ))
        {
            print_len = sprintf((char *)print_buf,"Write index:%d\r\n",( arg_int8->arg ));
            gaoz_usb_driver_send_data( print_buf, print_len );
            step ++;
        }
    }
    /*2、解析发送的数据和长度，向发送数据*/
    if( step == 1 )
    {
        unit_arg_str = (unit_arg_str_type *)&arg[arg_len];
        if(( unit_arg_str->num == 2 ) 
            && (( unit_arg_str->len > 0 ) && ( unit_arg_str->len < UNIT_ARG_STR_MAX_LEN )))
        {
            write_len = unit_arg_str->len;
            write_buf = unit_arg_str->arg;
            step ++;
        }
        arg_len += unit_arg_str->len + 3;
    }
    /*3、写数据*/
    if( step == 2 )
    {
        ret = gaoz_ble_drive_data_write( write_buf , write_len );
        if( ret == pdPASS )
        {   
            print_len = sprintf((char *)print_buf,"Write data:%d,%s\r\n",write_len ,write_buf);
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
    }
    
    if( print_buf != NULL )
    {
        gaoz_free_mem( (void *)print_buf );
    }
    return ret;
}

static void  unit_ble_read_handle_task( void * pvParameters)
{ 
    uint8_t ble_read_buf[200] = { 0 };
    uint16_t ble_read_len = 0;
    uint8_t  print_buf[200] = { 0 };
    uint16_t print_len = 0;
    for( ;; )
    {
        if( gaoz_ble_drive_data_read( (uint8_t *)ble_read_buf , &ble_read_len , 1000 ) == pdPASS )
        {
            print_len = sprintf((char *)print_buf,"Read data:%d,%s",ble_read_len ,ble_read_buf);
            print_buf[print_len] = '\r';
            print_len++;
            print_buf[print_len] = '\n';
            print_len++;
            gaoz_usb_driver_send_data( print_buf, print_len );
        }
        else
        {
             if( ble_connect_st == 0 )
             {  
                print_len = sprintf((char *)print_buf,"Read task exit\r\n");
                gaoz_usb_driver_send_data( print_buf, print_len );
                gaoz_thread_delete();
             }
        }
    }
}

static uint32_t unit_ble_read( uint8_t n , uint8_t *arg )
{
    uint16_t arg_len = 0;
    unit_arg_int8_type *arg_int8 = NULL;
    uint8_t  print_buf[200] = { 0 };
    uint16_t print_len = 0;
    uint32_t ret = pdFAIL;
    if( n != 1 )
    {
        return  pdFAIL;
    }
    arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
    arg_len += sizeof( unit_arg_int8_type );
    if(( arg_int8->num == 1 ) 
        && ( arg_int8->len == 0x01 ) 
        && ( arg_int8->arg > 0 ) )
    {
            print_len = sprintf((char *)print_buf,"Read index:%d\r\n",( arg_int8->arg ));
            gaoz_usb_driver_send_data( print_buf, print_len );
            if( ble_connect_st == 1 )
            {
                if( gaoz_thread_create( unit_ble_read_handle_task, "unit_ble_read" ,1024*4, NULL, OSI_PRIORITY_NORMAL) == 0 )
                {
                    print_len = sprintf((char *)print_buf,"Read task creat successful\r\n");
                    gaoz_usb_driver_send_data( print_buf, print_len );
                    ret = pdPASS;
                }
            }
    }
    
    return ret;
}

static uint32_t unit_ble_close( uint8_t n , uint8_t *arg )
{
    uint16_t arg_len = 0;
    uint32_t ret = pdFAIL ;
    uint8_t  print_buf[100] = { 0 };
    uint16_t print_len = 0;
    unit_arg_int8_type *arg_int8 = NULL;
    
    if( n != 1 )
    {
        return  pdFAIL;
    }
    arg_int8 =(unit_arg_int8_type *)&arg[arg_len];
    arg_len += sizeof( unit_arg_int8_type );
    if(( arg_int8->num == 1 )&& ( arg_int8->len == 0x01 ))
    {
        if( arg_int8->arg == 1 )
        {   
            ret = gaoz_ble_drive_data_close( "GAOZ_BLE_001" );
            if( ret == pdPASS )
            {
                ble_connect_st = 0;
                print_len = sprintf( (char *)print_buf,"Flash close successful:%d\r\n",arg_int8->arg );
                gaoz_usb_driver_send_data( print_buf, print_len );
                ret = pdPASS;
            }
        }
    }
    
    return ret;
}

const unit_test_interface_typedef unit_ble_mod =
{
    UNIT_BLE,            	// 模块类型
    "BLE",              	// 模块名称
    unit_ble_open,	
    unit_ble_write,       	
    unit_ble_read,         	
    NULL,
    unit_ble_close,
};

